1   /*
2    * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  package com.sun.media.sound;
26  
27  /**
28   * LFO control signal generator.
29   *
30   * @author Karl Helgason
31   */
32  public class SoftLowFrequencyOscillator implements SoftProcess {
33  
34      private int max_count = 10;
35      private int used_count = 0;
36      private double[][] out = new double[max_count][1];
37      private double[][] delay = new double[max_count][1];
38      private double[][] delay2 = new double[max_count][1];
39      private double[][] freq = new double[max_count][1];
40      private int[] delay_counter = new int[max_count];
41      private double[] sin_phase = new double[max_count];
42      private double[] sin_stepfreq = new double[max_count];
43      private double[] sin_step = new double[max_count];
44      private double control_time = 0;
45      private double sin_factor = 0;
46      private static double PI2 = 2.0 * Math.PI;
47  
48      public SoftLowFrequencyOscillator() {
49          // If sin_step is 0 then sin_stepfreq must be -INF
50          for (int i = 0; i < sin_stepfreq.length; i++) {
51              sin_stepfreq[i] = Double.NEGATIVE_INFINITY;
52          }
53      }
54  
55      public void reset() {
56          for (int i = 0; i < used_count; i++) {
57              out[i][0] = 0;
58              delay[i][0] = 0;
59              delay2[i][0] = 0;
60              freq[i][0] = 0;
61              delay_counter[i] = 0;
62              sin_phase[i] = 0;
63              // If sin_step is 0 then sin_stepfreq must be -INF
64              sin_stepfreq[i] = Double.NEGATIVE_INFINITY;
65              sin_step[i] = 0;
66          }
67          used_count = 0;
68      }
69  
70      public void init(SoftSynthesizer synth) {
71          control_time = 1.0 / synth.getControlRate();
72          sin_factor = control_time * 2 * Math.PI;
73          for (int i = 0; i < used_count; i++) {
74              delay_counter[i] = (int)(Math.pow(2,
75                      this.delay[i][0] / 1200.0) / control_time);
76              delay_counter[i] += (int)(delay2[i][0] / (control_time * 1000));
77          }
78          processControlLogic();
79      }
80  
81      public void processControlLogic() {
82          for (int i = 0; i < used_count; i++) {
83              if (delay_counter[i] > 0) {
84                  delay_counter[i]--;
85                  out[i][0] = 0.5;
86              } else {
87                  double f = freq[i][0];
88  
89                  if (sin_stepfreq[i] != f) {
90                      sin_stepfreq[i] = f;
91                      double fr = 440.0 * Math.exp(
92                              (f - 6900.0) * (Math.log(2) / 1200.0));
93                      sin_step[i] = fr * sin_factor;
94                  }
95                  /*
96                  double fr = 440.0 * Math.pow(2.0,
97                  (freq[i][0] - 6900.0) / 1200.0);
98                  sin_phase[i] += fr * sin_factor;
99                   */
100                 /*
101                 sin_phase[i] += sin_step[i];
102                 while (sin_phase[i] > PI2)
103                 sin_phase[i] -= PI2;
104                 out[i][0] = 0.5 + Math.sin(sin_phase[i]) * 0.5;
105                  */
106                 double p = sin_phase[i];
107                 p += sin_step[i];
108                 while (p > PI2)
109                     p -= PI2;
110                 out[i][0] = 0.5 + Math.sin(p) * 0.5;
111                 sin_phase[i] = p;
112 
113             }
114         }
115     }
116 
117     public double[] get(int instance, String name) {
118         if (instance >= used_count)
119             used_count = instance + 1;
120         if (name == null)
121             return out[instance];
122         if (name.equals("delay"))
123             return delay[instance];
124         if (name.equals("delay2"))
125             return delay2[instance];
126         if (name.equals("freq"))
127             return freq[instance];
128         return null;
129     }
130 }